home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / dosutil / bootmenu.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  5KB  |  197 lines

  1. /*
  2.  * BOOTMENU: a DOS Startup menu that automatically reloads with
  3.  * different AUTOEXEC.BAT and CONFIG.SYS if necessary.
  4.  *
  5.  * Copyright 1992-1994 Dave Dunfield
  6.  * All rights reserved.
  7.  *
  8.  * Permission granted to use for personal (non-commercial) use only.
  9.  *
  10.  * Compile command: cc bootmenu -fop
  11.  */
  12. #include <stdio.h>        /* Standard I/O definitions */
  13. #include <window.h>        /* Windowing library definitions */
  14.  
  15. #define    MAXCFG    10        /* Maximum number of menu entries supported */
  16.  
  17. char description[MAXCFG][71], autoexec[MAXCFG][51], config[MAXCFG][51],
  18.     old_autoexec[51], old_config[51], *parse_ptr, reboot = 0, *boot_dir;
  19.  
  20. unsigned cfg_count = 0, max_length = 0, select = 0, timer = 10;
  21.  
  22. /*
  23.  * Parse a string delimited by '|' from the input line
  24.  */
  25. parse(dest)
  26.     char *dest;
  27. {
  28.     while(isspace(*parse_ptr))
  29.         ++parse_ptr;
  30.     while(*parse_ptr) {
  31.         if((*dest = *parse_ptr++) == '|')
  32.             break;
  33.         ++dest; }
  34.     *dest = 0;
  35. }
  36.  
  37. /*
  38.  * Main program - check if in "reboot phase", and if so, terminate with
  39.  * proper error code. Otherwise, give menu of available options.
  40.  */
  41. main(argc, argv)
  42.     int argc;
  43.     char *argv[];
  44. {
  45.     unsigned i, j, s, s1;
  46.     char buffer[150], buffer1[50];
  47.     FILE *fp;
  48.  
  49.     if(argc > 1)        /* Directory is specified */
  50.         boot_dir = argv[1];
  51.     else {                /* Use directory from program name */
  52.         boot_dir = argv[i=j=0];
  53.         while(s = boot_dir[i]) {
  54.             if(s == '\\')
  55.                 j = i;
  56.             ++i; }
  57.         boot_dir[j] = 0; }
  58.  
  59.     /* If re-booting to establish configuration */
  60.     sprintf(buffer, "%s\\BOOTMENU.CTL", boot_dir);
  61.     if(fp = fopen(buffer, "rv")) {
  62.         fgets(buffer, sizeof(buffer)-1, fp);
  63.         fgets(old_autoexec, sizeof(old_autoexec)-1, fp);
  64.         fgets(old_config, sizeof(old_config)-1, fp);
  65.         fclose(fp);
  66.         select = atoi(buffer+1);
  67.         if(*buffer == '*')
  68.             goto xboot; }
  69.  
  70.     /* Read in configuration directory file */
  71.     sprintf(buffer,"%s\\BOOTMENU.CFG", boot_dir);
  72.     fp = fopen(buffer, "rvq");
  73.     parse_ptr = fgets(buffer, sizeof(buffer)-1, fp);
  74.     parse(buffer1);
  75.     if(*buffer1)
  76.         timer = atoi(buffer1);
  77.     parse(buffer1);
  78.     if(*buffer1)
  79.         select = atoi(buffer1);
  80.     while(parse_ptr = fgets(buffer, sizeof(buffer)-1, fp)) {
  81.         parse(description[cfg_count]);
  82.         parse(autoexec[cfg_count]);
  83.         parse(config[cfg_count]);
  84.         max_length = max(max_length, strlen(description[cfg_count]));
  85.         ++cfg_count; }
  86.     fclose(fp);
  87.  
  88.     /* Open window & indicate available options */
  89.     wopen(40-(max_length+8)/2, 12-(cfg_count+3)/2, max_length+8, cfg_count+3,
  90.         WSAVE|WBOX1|WCOPEN|0x70);
  91.     wcursor_off();
  92.     for(i=0; i < cfg_count; ++i) {
  93.         wprintf("%c%u - %s\n", (i == select) ? '*' : ' ', i, description[i]); }
  94.  
  95.     wprintf("Select: %u", timer);
  96.  
  97.     /* Wait for user to choose selection, or timeout */
  98.     get_time(&j, &j, &s);
  99.     do {
  100.         if(i = wtstc()) {
  101.             if((i == '\n') || (i == ' ') || (i == 0x1B))
  102.                 break;
  103.             if((i - '0') < cfg_count) {
  104.                 select = i - '0';
  105.                 break; } }
  106.         get_time(&j, &j, &s1);
  107.         if(s != s1) {
  108.             s = s1;
  109.             wprintf("\rSelect: %u ", --timer); } }
  110.     while(timer && (i != ' ') && (i != '\n'));
  111.     wclose();
  112.  
  113.     /* If new config uses a different AUTOEXEC, copy it over */
  114.     parse_ptr = autoexec[select];
  115.     if(*parse_ptr && strcmp(parse_ptr, old_autoexec)) {
  116.         strcpy(old_autoexec, parse_ptr);
  117.         copy_files("\\AUTOEXEC.BAT", parse_ptr); }
  118.  
  119.     /* If new config uses a different CONFIG, copy it over */
  120.     parse_ptr = config[select];
  121.     if(*parse_ptr && strcmp(parse_ptr, old_config)) {
  122.         strcpy(old_config, parse_ptr);
  123.         copy_files("\\CONFIG.SYS", parse_ptr); }
  124.  
  125. xboot:
  126.  
  127.     /* Rewrite control file to reflect current state */
  128.     sprintf(buffer, "%s\\BOOTMENU.CTL", boot_dir);
  129.     fp = fopen(buffer, "wvq");
  130.     fprintf(fp,"%c%u\n%s\n%s", reboot ? '*' : '-', select, old_autoexec, old_config);
  131.     fclose(fp);
  132.  
  133.     /* If files have changed - REBOOT! */
  134.     if(reboot) asm {
  135.         MOV        AH,0Dh                    ; Disk RESET function
  136.         INT        21h                        ; Ask DOS
  137.         MOV        AX,40h                    ; BIOS data area
  138.         MOV        ES,AX                    ; Set ES
  139.         MOV        WORD PTR ES:72h,1234h    ; Indicate warm start
  140.         DB        0EAh,0,0,0FFh,0FFh        ; JMP FAR FFFF:0
  141.     }
  142.  
  143.     /* Pass back selection number as errorlevel */
  144.     exit(select);
  145. }
  146.  
  147. /*
  148.  * Copy one or more files from our directory to the destination
  149.  */
  150. copy_files(dest, source)
  151.     char *dest, *source;
  152. {
  153.     char buffer[150], name[15], *ptr, data_flag;
  154.     FILE *fpd, *fps;
  155.  
  156.     fpd = fopen(dest, "wvq");
  157.  
  158.     /* Copy files(s) into output file */
  159.     while(*source) {
  160.         data_flag = 0;
  161.         /* Concatinate directory and source file */
  162.         dest = buffer;
  163.         ptr = boot_dir;
  164.         while(*dest = *ptr++)
  165.             ++dest;
  166.         *dest++ = '\\';
  167.         if(*source == '!') {            /* From general file */
  168.             strcpy(dest, "BOOTMENU.DAT");
  169.             dest = name;
  170.             data_flag = -1; }
  171.         while(*source) {                /* Copy in file name */
  172.             if((*dest = *source++) == ',')
  173.                 break;
  174.             ++dest; }
  175.         *dest = 0;
  176.         /* Copy data into new file */
  177.         fps = fopen(buffer, "rvq");
  178.         if(data_flag) {                    /* Copy from general file */
  179.             while(fgets(buffer, sizeof(buffer)-1, fps)) {
  180.                 if(*buffer == '!') {
  181.                     if(!data_flag)
  182.                         break;
  183.                     if(!strcmp(buffer, name))
  184.                         data_flag = 0; }
  185.                 else if(!data_flag) {
  186.                     fputs(buffer, fpd);
  187.                     putc('\n', fpd); } } }
  188.         else {                            /* Copy from separate file */
  189.             while(fgets(buffer, sizeof(buffer)-1, fps)) {
  190.                 fputs(buffer, fpd);
  191.                 putc('\n', fpd); } }
  192.         fclose(fps); }
  193.  
  194.     fclose(fpd);
  195.     reboot = -1;
  196. }
  197.